import {Injectable} from "@angular/core";
import 'rxjs/add/operator/toPromise';
import {Response, Http} from "@angular/http";
import {ResultEntity} from "../model/resultEntity";
import {Constant} from "../model/Constant";

/**
 * A class that used to request remote server.
 * Created by wubin on 2016-04-30.
 */
@Injectable()
export class RequestServerHTTPService {
    constructor(private _http: Http) {
    }

    /**
     * Get request to remote server, and the server should return result for callback.
     * @param url request's url
     * @param data this is one object, for example{name:value}, will be appended to url as request's parameter,
     *         like url?name=value.
     * @param succeedFn when request succeed, will callback this method.
     * @param defeatFn when request's process has some errors, will callback this method.
     */
    getRequestServerForBack(url, data, succeedFn, defeatFn): void {
        url = RequestServerHTTPService.generateUrlByParam(url, data);
        this.requestServer(url).then(result => {
            succeedFn(result)
        }, errorMsg => defeatFn(errorMsg));
    }

    /**
     * Get request to remote server, no result from remote server.
     * @param url request's url
     * @param data this is one object, for example{name:value}, will be appended to url as request's parameter,
     *         like url?name=value.
     */
    getRequestWithoutBack(url, data): void {
        url = RequestServerHTTPService.generateUrlByParam(url, data);
        location.href = url;
        // this._http.get(url).toPromise().then(null).catch(null);
        // alert("after get");
    }

    private static generateUrlByParam(url: string, data: any): string {
        if (data != null) {
            let requestUrl = url + "?";
            if (data.implement && data.implement === Constant.generate_param_label) {
                requestUrl += data.generateParam();
            } else {
                for (let param in data) {
                    if (data.hasOwnProperty(param)) {
                        requestUrl += param + "=" + data[param] + "&"
                    }
                }
                requestUrl = requestUrl.substring(0, requestUrl.length - 1);
            }

            return requestUrl;
        } else {
            return url;
        }
    }

    private requestServer(url: any): Promise<any> {
        return this._http.get(url)
            .toPromise()
            .then(RequestServerHTTPService.extractData)
            .catch(RequestServerHTTPService.operateError);
    }

    private static extractData(res: Response): ResultEntity {
        if (res.status < 200 || res.status >= 300) {
            throw new Error('Bad response status: ' + res.status);
        }
        let body = res.json();
        return new ResultEntity(body.result);
    }

    private static operateError(error: any) {
        let errMsg = error.message || 'Server error';
        return Promise.reject(errMsg);
    }
}